#import "PointOfInterest.h"

/**
 * A PointOfInterest is an object representing a single point of 
 * interest.
 *
 * Conforms to the PersistentDataType protocol.
 *
 * @author      Justin Hollander
 * @version     1.4.1
 * @since       0.1.0
 * @see         PersistentDataType
 */
@implementation PointOfInterest

@synthesize category;
@synthesize poiTags;
@synthesize isSelected;
@synthesize desc;

/**
 * Initialize the point of interest.
 *
 * @return  the initialized point of interest
 */
- (id)init {
	if (self = [super init]) {
		self.name = @"";
	}
	
	return self;
}

/**
 * Initialize the point of interest with given information.
 *
 * @param nm             the name of the point of interest
 * @param location       location of the point of interest
 * @param cat            the category of the point of interest
 * @param selectedState  whether the point of interest is selected
 * @return               the initialized point of interest with details
 */
- (id)initWithDetails:(NSString*)nm 
				point:(GPSLocation*)location 
			 category:(PointOfInterestCategory)cat 
			 selected:(BOOL)selectedState {
	if (self = [super initWithDetails:nm point:location]){
		self.category = cat;
		self.isSelected = selectedState;
		self.poiTags = [NSMutableArray array];
	}
	
	return self;
}

/**
 * Initialize the point of interest with given information.
 *
 * @param nm             the name of the point of interest
 * @param location       location of the point of interest
 * @param cat            the category of the point of interest
 * @param tags           the list of tags associated with the point of interest
 * @param selectedState  whether the point of interest is selected
 * @return               the initialized point of interest with details
 */
- (id)initWithDetails:(NSString*)nm 
				point:(GPSLocation*)location 
			 category:(PointOfInterestCategory)cat 
			  tagList:(NSArray*)tags
			 selected:(BOOL)selectedState {
	if (self = [self initWithDetails:nm 
							   point:location 
							category:cat 
							selected:selectedState]){
		
		[poiTags addObjectsFromArray:tags];
	}
	
	return self;
}

/**
 * Initialize the point of interest with given information.
 *
 * @param nm             the name of the point of interest
 * @param description    the description of the point of interest
 * @param location       location of the point of interest
 * @param cat            the category of the point of interest
 * @param tags           the list of tags associated with the point of interest
 * @param selectedState  whether the point of interest is selected
 * @return               the initialized point of interest with details
 */
- (id)initWithDetails:(NSString*)nm 
		  description:(NSString*)description
				point:(GPSLocation*)location 
			 category:(PointOfInterestCategory)cat 
			  tagList:(NSArray*)tags
			 selected:(BOOL)selectedState {
	if (self = [self initWithDetails:nm 
							   point:location 
							category:cat 
							selected:selectedState]){
		self.desc = description;
		[poiTags addObjectsFromArray:tags];
	}
	
	return self;
}

/**
 * Initialize the point of interest given another one.
 *
 * @param poi  the other point of interest with which to initialize
 * @return     the initialized point of interest 
 */
- (id)initWithPOI:(PointOfInterest*)poi {
	if (self = [super initWithDetails:poi.name point:poi.loc]) {
		self.category = poi.category;
		self.poiTags = poi.poiTags;
		self.isSelected = poi.isSelected;
	}
	
	return self;
}

/**
 * Initializes the point of interest from archive.
 *
 * @param coder  the NSCoder used for decoding
 * @return       the point of interest decoded from archive
 */
- (id)initWithCoder:(NSCoder*)coder {
	if ((self = [super init]) && ([coder allowsKeyedCoding])){
		[super initWithCoder:coder];
		self.desc = [coder decodeObjectForKey:@"POIDesc"];
		self.category = [coder decodeIntForKey:@"POICategory"];
		self.poiTags = [coder decodeObjectForKey:@"POITags"];
		self.isSelected = [coder decodeBoolForKey:@"SelectedState"];
	}
	
	return self;
}

/**
 * Encodes the point of interest for archiving options.
 *
 * @param coder  the NSCoder used for encoding
 */
-(void)encodeWithCoder:(NSCoder*)coder{
	if ([coder allowsKeyedCoding]) {
		[super encodeWithCoder:coder];
		[coder encodeObject:self.desc forKey:@"POIDesc"];
		[coder encodeInt:self.category forKey:@"POICategory"];
		[coder encodeObject:self.poiTags forKey:@"POITags"];
		[coder encodeBool:self.isSelected forKey:@"SelectedState"];
	}
}

/**
 * Compute a unique key for the point of interest.
 *
 * @return  the unique key
 */
- (NSString*)getKey {
	return [[super getKey] stringByAppendingString:
			[SFUConstants POICategoryString:self.category]]; 
}

/**
 * Deallocate the point of interest.
 */
- (void)dealloc {
	[poiTags release];
	[super dealloc];
}

/**
 * Facilitate alphabetic sorting by category name.
 */
- (NSComparisonResult)compareCategory:(id)otherPOI {
	return [[SFUConstants POICategoryString:self.category] 
			compare:[SFUConstants POICategoryString:((PointOfInterest*)otherPOI).category]];
}

@end
